/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Galaxium.Core;
using Galaxium.Gui;

namespace Galaxium.Protocol.Irc
{
	public sealed class IrcChannel : AbstractContact
	{
		public event EntityChangeEventHandler<string> TopicChanged;
		public event EntityChangeEventHandler<bool> AutoJoinChanged;
		public event EntityChangeEventHandler<bool> PersistentChanged;
		public event EventHandler<ChannelModeEventArgs> ChannelModeChanged;
		public event EventHandler<ChannelEventArgs> ChannelBanListChanged;
		public event EventHandler<ChannelEventArgs> CannotSend;

		private string topic;
		private ChannelModeFlags flags = ChannelModeFlags.None;
		private List<string> banMasks;
		private List<string> excludeMasks;
		private int limit;
		private string key;
		private bool _autoJoin;
		private bool _persistent;
		private IrcStoredChannel _storedChannel;
		
		internal IrcStoredChannel StoredChannel
		{
			get { return _storedChannel; }
			set { _storedChannel = value; }
		}
		
		private ContactCollection contacts;

		public IrcChannel (IrcSession session, string channel, string key, bool autoJoin, bool persistent)
			: base (session, channel, channel, IrcPresence.Offline)
		{
			contacts = new ContactCollection ();
			banMasks = new List<string> ();
			excludeMasks = new List<string> ();
			limit = -1;
			this.key = key;
			this._autoJoin = autoJoin;
			this._persistent = persistent;
		}
		
		public void SetTopic (string topic)
		{
			this.topic = topic;
		}
		
		public ContactCollection ContactCollection
		{
			get { return contacts; }
		}
		
		public string Key
		{
			get { return key; }
			set { key = _storedChannel.Key = value; }
		}
		
		public string Topic
		{
			get { return topic; }
			set
			{
				if (topic != value)
				{
					string old = topic;
					topic = value;
					OnTopicChanged (new Galaxium.Protocol.EntityChangeEventArgs<string> (this, value, old));
				}
			}
		}

		public bool AutoJoin
		{
			get { return _autoJoin; }
			set
			{
				if (_autoJoin != value)
				{
					bool old = _autoJoin;
					_autoJoin = _storedChannel.AutoJoin = value;
					OnAutoJoinChanged (new Galaxium.Protocol.EntityChangeEventArgs<bool> (this, value, old));
				}
				
			}
		}
		
		public bool Persistent
		{
			get { return _persistent; }
			set
			{
				if (_persistent != value)
				{
					bool old = _persistent;
					_persistent = _storedChannel.Persistent = value;
					OnPersistentChanged (new Galaxium.Protocol.EntityChangeEventArgs<bool> (this, value, old));
				}
			}
		}
		
		public ChannelModeFlags ChannelFlags
		{
			get { return flags; }
			set { flags = value; }
		}

		public IList<string> BanMasks
		{
			get { return banMasks; }
		}

		public IList<string> ExcludeMasks
		{
			get { return excludeMasks; }
		}

		public int Limit
		{
			get { return limit; }
			set { limit = value; }
		}
		
		public bool HasChannelModes (ChannelModeFlags flag)
		{
			return (flags & flag) == flag;
		}
		
		private void OnAutoJoinChanged (EntityChangeEventArgs<bool> args)
		{
			if (AutoJoinChanged != null)
				AutoJoinChanged (this, args);
		}
		
		private void OnPersistentChanged (EntityChangeEventArgs<bool> args)
		{
			if (PersistentChanged != null)
				PersistentChanged (this, args);
		}
		
		private void OnTopicChanged (EntityChangeEventArgs<string> args)
		{
			if (TopicChanged != null)
				TopicChanged (this, args);
		}
		
		internal void EmitChannelModeChanged (ChannelModeEventArgs args)
		{
			if (ChannelModeChanged != null)
				ChannelModeChanged (this, args);
		}
		
		internal void EmitChannelBanListChanged (ChannelEventArgs args)
		{
			if (ChannelBanListChanged != null)
				ChannelBanListChanged (this, args);
		}
		
		internal void EmitCannotSend (ChannelEventArgs args)
		{
			if (CannotSend != null)
				CannotSend (this, args);
		}
	}
}